package cn.gobang.action;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.interceptor.ApplicationAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.alibaba.fastjson.JSON;

import cn.gobang.util.ResultUtils;

@ParentPackage("struts-default")
@Namespace("/")
@Controller
@Scope("prototype")
public class GoBangAction implements SessionAware,ServletResponseAware,ApplicationAware{
	
	/**
	 * 横坐标 ，0开始
	 */
	private Integer x;
	/**
	 * 纵坐标，0开始
	 */
	private Integer y;
	private Map<String, Object> session;
	private HttpServletResponse response;
	private Map<String, Object> application;
	
	public Integer getX() {
		return x;
	}
	public void setX(Integer x) {
		this.x = x;
	}
	public Integer getY() {
		return y;
	}
	public void setY(Integer y) {
		this.y = y;
	}
	
	//声明一个内部类，用于封装x,y
	class XAndY{
		private Integer u_x;
		private Integer u_y;
		public Integer getU_x() {
			return u_x;
		}
		public void setU_x(Integer u_x) {
			this.u_x = u_x;
		}
		public Integer getU_y() {
			return u_y;
		}
		public void setU_y(Integer u_y) {
			this.u_y = u_y;
		}
		//重写equals，hashcode方法
		public XAndY(Integer u_x, Integer u_y) {
			super();
			this.u_x = u_x;
			this.u_y = u_y;
		}
		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + getOuterType().hashCode();
			result = prime * result + ((u_x == null) ? 0 : u_x.hashCode());
			result = prime * result + ((u_y == null) ? 0 : u_y.hashCode());
			return result;
		}
		@Override
		public boolean equals(Object obj) {
			if(obj==null){
				return false;
			}
			if(obj!=null){
				XAndY xy=(XAndY)obj;
				if((xy.getU_x()==this.getU_x())&&(xy.getU_y()==this.getU_y())){
					return true;
				}
			}
			return false;
		}
		private GoBangAction getOuterType() {
			return GoBangAction.this;
		}
		
	}
	
	/**
	 * 判断当前用户是否胜利
	 * @param list 原来的棋盘的棋子，
	 * @param point 目前的棋子
	 * @return
	 */
	public boolean isWin(List<XAndY> list,XAndY point){
		System.out.println(list.size());
		
		//从当前点向左判断，判断当前点X轴的左边
		int times=4;
		int xline=0;//X轴上的棋子连续相连的数量
		while(times>0){
			if(list.contains(new XAndY(point.getU_x()-(5-times),point.getU_y()))){
				xline++;
				if(xline>=4){
					return true;
				}
			}else{
				break;
			}
			times--;
		}
		if(times==0 || xline>=4){
			return true;
		}
		//从当前点向右判断，判断当前点的X周的右边
		times=4;//右重新初始化为4个
		while(times>0){
			if(list.contains(new XAndY(point.getU_x()+(5-times),point.getU_y()))){
				xline++;
				if(xline>=4){
					return true;
				}
			}else{
				break;
			}
			times--;
		}
		if(times==0 || xline>=4){
			return true;
		}
		
		
		//从当前点向上判断，判断当前点Y周的上边
		int yline=0;//Y轴上的棋子连续相连的数量
		times=4;
		while(times>0){
			if(list.contains(new XAndY(point.getU_x(),point.getU_y()-(5-times)))){
				yline++;
				if(yline>=4){
					return true;
				}
			}else{
				break;
			}
			times--;
		}
		if(times==0 || yline>=4){
			return true;
		}
		//从当前点向下判断，判断当前Y轴的下边
		times=4;
		while(times>0){
			if(list.contains(new XAndY(point.getU_x(),point.getU_y()+(5-times)))){
				yline++;
				if(yline>=4){
					return true;
				}
			}else{
				break;
			}
			times--;
		}
		if(times==0 || yline >=4){
			return true;
		}
		
		
		
		
		//从当前点向左下判断，x值减1，y值加上1
		int xldyru=0;
		times=4;
		while(times>0){
			if(list.contains(new XAndY(point.getU_x()-(5-times),point.getU_y()+(5-times)))){
				xldyru++;
				if(xldyru>=4){
					return true;
				}
			}else{
				break;
			}
			times--;
		}
		if(times==0||xldyru>=4){
			return true;
		}
		//从当前点向右上判断，x值加1，y值减1
		times=4;
		while(times>0){
			if(list.contains(new XAndY(point.getU_x()+(5-times),point.getU_y()-(5-times)))){
				xldyru++;
				if(xldyru>=4){
					return true;
				}
			}else{
				break;
			}
			times--;
		}
		if(times==0 || xldyru>=4){
			return true;
		}
		
		
		//从当前点向左上判断
		int xruyrd=0;
		times=4;
		while(times>0){
			if(list.contains(new XAndY(point.getU_x()-(5-times),point.getU_y()-(5-times)))){
				xruyrd++;
				if(xruyrd>=4){
					return true;
				}
			}else{
				break;
			}
			times--;
		}
		if(times==0 || xruyrd>=4){
			return true;
		}
		//从当前点向右下判断
		times=4;
		while(times>0){
			if(list.contains(new XAndY(point.getU_x()+(5-times),point.getU_y()+(5-times)))){
				xruyrd++;
				if(xruyrd>=4){
					return true;
				}
			}else{
				break;
			}
			times--;
		}
		if(times==0 || xruyrd>=4){
			return true;
		}
		
		//当所有的判断经过了后，就返回false;
		return false;
	}

	/**
	 * 获得当前用户在每个List的String[]中占得位置
	 * @return 一个Int类型的数据，<br/>
	 * 			如果为0,表示占据第一个位置<br/>
	 * 			如果为1,表示占据第二个位置<br/>
	 * 			如果为-1,表示没有当前用户
	 */
	public int getNowStringArrayIndex(){
		List<String[]> lists = (List<String[]>)application.get("userlists");
		for(int lindex=0;lindex<lists.size();lindex++){//循环外层List
        	String[] each=lists.get(lindex);
        	for(int iindex=0;iindex<2;iindex++){//循环内部String[],只需要比较第一个和第二个，应为string[]存储数据的形式是{"用户1"，"用户2","状态码",目前的x值，目前的y值，目前是谁赢了}
        		if(session.get("username").equals(each[iindex])){
        			return iindex;
        		}
        	}
        }
		return -1;
	}
	/**
	 * 获得当前用户所在String[]的List集合的排序位置
	 * @return 一个Int类型的数据<br/>
	 * 			返回-1表示未找到数据
	 */
	public int getNowListIndex(){
		List<String[]> lists = (List<String[]>)application.get("userlists");
		for(int lindex=0;lindex<lists.size();lindex++){//循环外层List
        	String[] each=lists.get(lindex);
        	for(int iindex=0;iindex<2;iindex++){//循环内部String[],只需要比较第一个和第二个，应为string[]存储数据的形式是{"用户1"，"用户2","状态码",目前的x值，目前的y值，目前是谁赢了}
        		if(session.get("username").equals(each[iindex])){
        			return lindex;
        		}
        	}
        }
		return -1;
	}
	@Action(value="view")
	public void execute() throws IOException{
		List<String[]> lists = (List<String[]>)application.get("userlists");
		String[] oldinfo=lists.get(getNowListIndex());
		int uindex=getNowStringArrayIndex();
		if(!(uindex+"").equals(oldinfo[2])){//判断目前是否该这个用户下棋
			//不该当前的用户下棋的
			Map<String,String> map=new HashMap<String,String>();
			map.put("info", "-2");//返回-2，表示目前不该当前用户下棋
			ResultUtils.toJson(response, map);
		}else{
		//该当前的用户下棋
		//获得用户以前下的棋数据
		 List<XAndY> usersteps=(List<XAndY>)session.get("usersteps");
		 //用户当前下的棋
		 XAndY step=new XAndY(x,y);
		 
		 //获得当前用户的位置下标
		 int nowStrIndex=getNowStringArrayIndex();
		 
		//获得另一个用户的下棋数据
		String otherdata=oldinfo[nowStrIndex==0?7:6];//如果是0，就获取下标为7的用户的数据，如果是1，就或是下标为6的用户的数据
		List<XAndY> otherusersteps=new ArrayList<XAndY>();
		if(!otherdata.equals("")){
			String[] strs=otherdata.split("&");
			for(int i=0;i<strs.length;i++){
				String[] str=strs[i].split(":");
				XAndY strxay=new XAndY(Integer.valueOf(str[0]),Integer.valueOf(str[1]));
				otherusersteps.add(strxay);
			}
		}
		boolean repeat=false;
		 
		if(usersteps==null){//表明用户下的是第一步
			
			//判断另一个用户的数据
			if(otherusersteps.size()!=0){
				for(XAndY ustep:otherusersteps){
					if(step.equals(ustep)){//表明其它用户
						repeat=true;
					}
				}
			}
			
			if(repeat){//用户的棋，重复了
				Map<String,String> map=new HashMap<String,String>();
				map.put("info", "你不能下到这里");
				ResultUtils.toJson(response, map);
				return;//结束
			}

			
			 List<XAndY> firststep=new ArrayList<XAndY>();
			 firststep.add(step);
			 session.put("usersteps",firststep);
			 
			 
		}else{
			//判断用户下的是否已经重复
			for(XAndY ustep:usersteps){
				if(step.equals(ustep)){//表明用户输入这步棋，已经走过了
					repeat=true;
				}
			}
			//判断另一个用户的数据
			for(XAndY ustep:otherusersteps){
				if(step.equals(ustep)){//表明用户输入这步棋，已经走过了
					repeat=true;
				}
			}
			
			if(repeat){//用户的棋，重复了
				Map<String,String> map=new HashMap<String,String>();
				map.put("info", "你不能下到这里");
				ResultUtils.toJson(response, map);
				return;//结束
			}
			
			//把用户的这步棋存储到session中
			usersteps.add(step);
			session.put("usersteps",usersteps);
		}
		String winnderindex="-1";//谁也没赢
		
		//判断当前用户是否胜利是否胜利
		if(isWin((List<XAndY>)session.get("usersteps"),step)){//已经胜利
            winnderindex=getNowStringArrayIndex()+"";
            
            Map<String,String> map=new HashMap<String,String>();
            map.put("info", "3");//返回3，表示用用户胜利了
			map.put("infodetail",(String)(session.get("username"))+",你已经胜利了！");
			ResultUtils.toJson(response, map);
		}
		//对Application中的存储信息做同步，处理
		String now_x=x+"";
		String now_y=y+"";
		String whonext=getNowStringArrayIndex()==0?(1+""):(0+"");
		/*
		 *改变数据的状态 
		 */
		oldinfo[2]=whonext;
		oldinfo[3]=now_x;
		oldinfo[4]=now_y;
		oldinfo[5]=winnderindex;
		List<XAndY> nowinfo=(List<XAndY>)session.get("usersteps");
		StringBuffer strinfo=new StringBuffer();
		for(int i=0;i<nowinfo.size();i++){
			if(i==0){
				strinfo.append(nowinfo.get(i).u_x+":"+nowinfo.get(i).u_y);
			}else{
				strinfo.append("&"+nowinfo.get(i).u_x+":"+nowinfo.get(i).u_y);
			}
		}
		oldinfo[nowStrIndex+6]=strinfo.toString();
		}		
		Map<String,String> map=new HashMap<String,String>();
		map.put("info", "2");//返回2，表示情况正常
		ResultUtils.toJson(response, map);
	}
	public void setSession(Map<String, Object> session) {
		this.session=session;
	}
	public void setServletResponse(HttpServletResponse response) {
		this.response=response;
	}
	public void setApplication(Map<String, Object> application) {
		this.application=application;
	}
}
